package com.example.his.api.common;

import cn.hutool.core.util.StrUtil;
import com.example.his.api.exception.HisException;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.iai.v20180301.IaiClient;
import com.tencentcloudapi.iai.v20180301.models.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;

@Component
@Slf4j
public class FaceAuthUtil {
  
  @Value("${tencent.cloud.secretId}")
  private String secretId;
  
  @Value("${tencent.cloud.secretKey}")
  private String secretKey;
  
  @Value("${tencent.cloud.face.groupId}")
  private String groupId;
  
  @Value("${tencent.cloud.face.region}")
  private String region;
  
  /**
   * 验证人脸模型的函数
   * 通过比较两张照片的人脸相似度，并进行活体检测，来验证人脸模型的有效性。
   * 如果人脸相似度足够高且活体检测通过，则检查人员是否已存在于人员库中，如果不存在，则将该人员添加到人员库中。
   *
   * @param name 人员姓名
   * @param pid 人员ID
   * @param sex 人员性别
   * @param photo_1 身份证照片
   * @param photo_2 摄像头拍照照片
   * @return 是否验证通过
   */
  public boolean verifyFaceModel(String name, String pid, String sex, String photo_1, String photo_2) {
    boolean res;
    
    Credential cred = new Credential(secretId, secretKey);
    IaiClient client = new IaiClient(cred, region);
    
    //    进行人脸对比
    CompareFaceRequest compareFaceRequest = new CompareFaceRequest();
    compareFaceRequest.setImageA(photo_1);
    compareFaceRequest.setImageB(photo_2);
    CompareFaceResponse compareFaceResponse = null;
    try {
      compareFaceResponse = client.CompareFace(compareFaceRequest);
    } catch(TencentCloudSDKException e) {
      log.error("人脸对比失败", e);
      throw new HisException("人脸对比失败");
    }
    //    获取人脸对比的分数
    Float score = compareFaceResponse.getScore();
    if(score >= 50) {
      //      对比相似度高，执行静态活体验证
      DetectLiveFaceRequest detectLiveFaceRequest = new DetectLiveFaceRequest();
      detectLiveFaceRequest.setImage(photo_2);
      DetectLiveFaceResponse detectLiveFaceResponse = null;
      try {
        detectLiveFaceResponse = client.DetectLiveFace(detectLiveFaceRequest);
      } catch(TencentCloudSDKException e) {
        log.error("静态活体检测失败", e);
        throw new HisException("静态活体检测失败");
      }
      res = detectLiveFaceResponse.getIsLiveness();
      
    } else {
      res = false;
      return res;
    }
    //  判断人员库是否有该体检人
    if(res) {
      //      查询人员库中是否有该体检人
      GetPersonBaseInfoRequest getPersonBaseInfoRequest = new GetPersonBaseInfoRequest();
      getPersonBaseInfoRequest.setPersonId(pid);
      GetPersonBaseInfoResponse getPersonBaseInfoResponse = null;
      try {
        getPersonBaseInfoResponse = client.GetPersonBaseInfo(getPersonBaseInfoRequest);
      } catch(TencentCloudSDKException e) {
        log.error("查询人员库失败", e);
        throw new HisException("查询人员库失败");
      }
      String personName = getPersonBaseInfoResponse.getPersonName();
      if(personName == null) {
        //  把体检人添加到人员库
        CreatePersonRequest createPersonRequest = new CreatePersonRequest();
        createPersonRequest.setGroupId(groupId);
        createPersonRequest.setPersonId(pid);
        long gender = sex.equals("男") ? 1L : 2L;
        createPersonRequest.setGender(gender);
        createPersonRequest.setQualityControl(4L);
        createPersonRequest.setUniquePersonControl(4L);
        createPersonRequest.setPersonName(name);
        createPersonRequest.setImage(photo_1);
        CreatePersonResponse createPersonResponse = null;
        try {
          createPersonResponse = client.CreatePerson(createPersonRequest);
        } catch(TencentCloudSDKException e) {
          log.error("添加体检人到人员库失败", e);
          throw new HisException("添加体检人到人员库失败");
        }
        if(StrUtil.isNotBlank(createPersonResponse.getFaceId())) {
          log.debug("添加体检人到人员库成功");
        } else {
          log.error("添加体检人到人员库失败");
          throw new HisException("添加体检人到人员库失败");
        }
        
      }
      
      
    }
    
    
    return res;
  }
  
  
}
